/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package me.tomato3017.plugins.epicmusic.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import me.tomato3017.plugins.epicmusic.EpicMusic;
import me.tomato3017.plugins.epicmusic.audio.MusicData;
import me.tomato3017.plugins.epicmusic.region.RegionData;
import org.bukkit.entity.Player;

/**
 *
 * @author Anthony Kirksey <Anthony.Kirksey@gmail.com>
 */
public class PlayerMusicThread implements Runnable{
    private Player player;
    private int lastPlayedSong = -1;
    private long lastTimePlayed;
    private int lastSongLength;
    private String currentRegion;
    private List<MusicData> musicData;
    
    private PlayMusicThread playMusicThread;
    private StopMusicThread stopMusicThread;
    private EpicMusic plugin;
    
    //Incoming data from main thread
    private String nextRegion;
    private boolean newRegion = false;
    
    public PlayerMusicThread(EpicMusic plugin, Player player, RegionData currentRegion) {
        this.player = player;
        this.plugin = plugin;
        
        this.currentRegion = currentRegion.getRegionName();
        setMusicData(currentRegion.getMusicPlaylist());
        
        playMusicThread = new PlayMusicThread();
        playMusicThread.setPlayer(player);
        
        stopMusicThread = new StopMusicThread(player);
    }

    public void run() {
        long time = System.currentTimeMillis();
        
        if(newRegion){ //updates the data in the thread with the new region.
            if(EpicMusic.isDEBUG()){
                EpicMusic.debugLog("NEW REGION FLAG TRUE Player:" + player.getName(), 3);
            }
            if(nextRegion != null){
                currentRegion = nextRegion;
                nextRegion = null;
                lastTimePlayed = System.currentTimeMillis() + 1000;
                lastSongLength = 0;
                
                setMusicData(EpicMusic.getRegionManager().GetRegion(currentRegion).getMusicPlaylist());
                
                EpicMusic.debugLog("Thread UPDATED!", 3);
                //stop any music that may be playing
                plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, stopMusicThread); 
            }
            
            
            newRegion = false;
        }
        //Check to see if the song is finished playing(+10 seconds)
        if((time - lastTimePlayed) >  (lastSongLength + EpicMusic.getTimeBetween())){
            MusicData nextSong = getNextSong();
            
            if(nextSong == null){
                lastSongLength = EpicMusic.getDefaultSongLength();
                lastTimePlayed = time;
                lastPlayedSong = -1;
                return;
            }
            
            lastSongLength = nextSong.getSongLength() * 1000;
            if(lastSongLength == 0)
                lastSongLength = EpicMusic.getDefaultSongLength();
            
            lastTimePlayed = time;
            playMusicThread.setMusicData(nextSong);
            plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, playMusicThread);
        }
        
    }

    //TODO: Convert this to use a shuffled playlist per region
    private MusicData getNextSong(){
        List<MusicData> mData = getMusicData();
        synchronized(mData){
            int numOfSongs = mData.size();
            int select = 0;
            
            if(mData.isEmpty())
                return null;
            
            //If only 1 song exists, skip it 1 cycle before replaying.
            if(numOfSongs < 2 && lastPlayedSong != -1)
                return null;
            
            Random rGen = new Random();
            
            int counter = 0;
            while(counter < 1000){ // To prevent the while loop from going into an infinite loop
                select = rGen.nextInt(numOfSongs);
                
                if(select != lastPlayedSong){
                    lastPlayedSong = select;
                    return mData.get(select);
                }
            }
            
            EpicMusic.debugLog("Thread song select timeout! Last song:" + lastPlayedSong, 3);
            return null;
        }
    }

    /**
     * @return the currentRegion
     */
    public synchronized String getCurrentRegion() {
        return currentRegion;
    }

    /**
     * @param currentRegion the currentRegion to set
     */
    public synchronized void setCurrentRegion(String currentRegion) {
        this.currentRegion = currentRegion;
    }

    public List<MusicData> getMusicData() {
        return musicData;
    }

    public void setMusicData(List<MusicData> musicData) {
        if(musicData == null){
            this.musicData = new ArrayList<MusicData>();
            return;
        }
        this.musicData = musicData;
    }

    public synchronized void setNextRegion(String region){
        this.nextRegion = region;
    }
    
    
    public synchronized void updateThread(){
        this.newRegion = true;
    }
    
    
    
}
